package com.tckdq.tcc.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.tckdq.tcc.constants.RedisConstant;
import com.tckdq.tcc.domain.Course;
import com.tckdq.tcc.domain.CourseMarket;
import com.tckdq.tcc.domain.CourseOrder;
import com.tckdq.tcc.domain.CourseOrderItem;
import com.tckdq.tcc.dto.CourseOrderParamDTO;
import com.tckdq.tcc.dto.PayOrder2MQDTO;
import com.tckdq.tcc.exception.GlobalException;
import com.tckdq.tcc.feign.CourseFeign;
import com.tckdq.tcc.mapper.CourseOrderMapper;
import com.tckdq.tcc.result.JsonResult;
import com.tckdq.tcc.service.ICourseOrderItemService;
import com.tckdq.tcc.service.ICourseOrderService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.tckdq.tcc.utils.CodeGenerateUtils;
import com.tckdq.tcc.vo.CourseDataForOrderVO;
import com.tckdq.tcc.vo.CourseOrderDataitemVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.Topic;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author whale
 * @since 2022-08-27
 */
@Service
public class CourseOrderServiceImpl extends ServiceImpl<CourseOrderMapper, CourseOrder> implements ICourseOrderService {

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    private CourseFeign courseFeign;

    @Autowired
    private ICourseOrderItemService courseOrderItemService;

    @Autowired
    private RocketMQTemplate mqTemplate;
    @Override
    public void placeOrder(CourseOrderParamDTO dto) {
        //1.参数校验
        //校验redis
        //courseIds集合转字符串
        List<Long> courseIds = dto.getCourseIds();
        String Ids = StringUtils.join(courseIds, ",");

        Long logId=3L;
        String token = (String) redisTemplate.opsForValue().get(RedisConstant.ORDER_TOKEN + logId + Ids);
        if (StringUtils.isEmpty(token)){
            throw new GlobalException("不要重复提交,或者请求过期",null);
        }
        if (!dto.getToken().equals(token)){
            throw new GlobalException("非法请求",null);
        }

        //获取课程数据
        JsonResult jsonResult = courseFeign.selCourseForOrder(Ids);
        if (!jsonResult.isSuccess()){
            throw new GlobalException(jsonResult.getMessage(),null);
        }
        if (org.springframework.util.StringUtils.isEmpty(jsonResult.getData())){
            throw new GlobalException("获取课程数据失败",null);
        }

        //feign调用的,转化成json字符串,再是json对象
        String jsonString = JSON.toJSONString(jsonResult);
        CourseDataForOrderVO orderVO = JSON.parseObject(jsonString, CourseDataForOrderVO.class);

        BigDecimal totalAmount = orderVO.getTotalAmount();
        List<CourseOrderDataitemVO> courseinfos = orderVO.getCourseinfos();

        ArrayList<CourseOrderItem> Items = new ArrayList<>();

        Date now = new Date();

        String orderSn = CodeGenerateUtils.generateOrderSn(logId);

        //累加商品数量
        int totalCount =0;

        StringBuilder sb = new StringBuilder();
        sb.append("购买:");
        //遍历大VO里的课程信息对象,里面包含课程和课程营销,然后把他们设置进订单详情里,再把订单详情装进List
        for (CourseOrderDataitemVO courseinfo : courseinfos) {
            //订单明细详情
            CourseOrderItem item = new CourseOrderItem();
            Course course = courseinfo.getCourse();
            CourseMarket courseMarket = courseinfo.getCourseMarket();

            item.setAmount(courseMarket.getPrice());
            item.setCount(1);
            totalCount=totalCount+item.getCount();
            item.setCourseId(course.getId());
            item.setCourseName(course.getName());
            item.getCoursePic(course.getPic());
            item.setCreateTime(now);
            item.setOrderNo(orderSn);
            item.getSubtotalAmount(courseMarket.getPrice().multiply(new BigDecimal(item.getCount())));
            sb.append(course.getName()).append(";");

            Items.add(item);
        }
        //创建订单
        CourseOrder courseOrder = new CourseOrder();
        sb.append("支付:"+totalAmount+"元");

        courseOrder.setCreateTime(now);
        courseOrder.setDiscountAmount(new BigDecimal("0"));
        courseOrder.setOrderNo(orderSn);
        courseOrder.setOrderType(dto.getType());
        courseOrder.setStatusOrder(CourseOrder.STATE_WAIT_PAY);
        courseOrder.setTitle(sb.toString());
        courseOrder.setTotalCount(totalCount);
        courseOrder.setUserId(logId);
        //insert(courseOrder);

        //把订单详情设置到订单里
        courseOrder.setItems(Items);

        //把订单id设置到订单详情里
      /*  for (CourseOrderItem item : Items) {
            item.setOrderId(courseOrder.getId());
        }
        courseOrderItemService.insertBatch(Items);*/

        PayOrder2MQDTO payOrder2MQDTO = new PayOrder2MQDTO(
                courseOrder.getPayAmount(),courseOrder.getPayType(),courseOrder.getOrderNo(),
                logId,"",courseOrder.getTitle());


        Message<String> payOrderMessage = MessageBuilder.withPayload(JSON.toJSONString(payOrder2MQDTO)).build();

        mqTemplate.sendMessageInTransaction(
                "tx_producer_group_courseorder"
                , "topic-payorder:tags-payorder"
                ,payOrderMessage
                ,courseOrder);


        //删除redis的token
        redisTemplate.delete(RedisConstant.ORDER_TOKEN + logId + Ids);
    }

    @Override
    public void saveOrderAndItem(CourseOrder courseOrder) {
        if (!org.springframework.util.StringUtils.isEmpty(seectlByOrderNo(courseOrder.getOrderNo()))){
            throw new GlobalException("訂單已經存在",null);
        }
        //保存订单
        insert(courseOrder);

        //保存订单id在订单详情
        courseOrder.getItems().forEach(item ->{
                    item.setOrderId(courseOrder.getId());
                    courseOrderItemService.insert(item);
                }
                );
    }

    private CourseOrder seectlByOrderNo(String orderNo) {
        EntityWrapper<CourseOrder> wrapper = new EntityWrapper<>();
        wrapper.eq("order_no",orderNo);
        CourseOrder courseOrder = selectOne(wrapper);
        return courseOrder;
    }
}
